package com.automation.utils;

import com.automation.entity.*;
import com.automation.service.AppiumUtils;
import io.appium.java_client.AppiumBy;
import io.appium.java_client.TouchAction;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.options.UiAutomator2Options;
import io.appium.java_client.touch.WaitOptions;
import io.appium.java_client.touch.offset.PointOption;
import org.openqa.selenium.By;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.net.MalformedURLException;
import java.net.URL;
import java.time.Duration;
import java.util.*;

public class AnMainTest {
    public static AndroidDriver driver;
    private static final String APP_PACKAGE = "com.dianping.v1";
    private static final String APP_ACTIVITY = ".NovaMainActivity";

    //    public static void setup() throws MalformedURLException {
//        UiAutomator2Options options = new UiAutomator2Options()
//                .setUdid("emulator-5554") // 设备ID
//                .setAppPackage(APP_PACKAGE)
//                .setAppActivity(APP_ACTIVITY)
//                .setAutoGrantPermissions(true)
//                .setNoReset(false);
//
//        driver = new AndroidDriver(new URL("http://127.0.0.1:4723"), options);
//        driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
//    }

    private static final String APPIUM_SERVER_URL = "http://127.0.0.1:4723/wd/hub";

    public static AndroidDriver init() {
        try {
            // 1. 创建选项对象
            UiAutomator2Options options = new UiAutomator2Options();

            // 2. 设置基础能力
            options.setPlatformName("Android");
            options.setPlatformVersion("7.1.2");
            options.setUdid("127.0.0.1:5555"); // 关键：只设置udid
            options.setAutomationName("UiAutomator2");

            // 3. 应用配置
//            options.setAppPackage("com.netease.cloudmusic");
            options.setAppActivity(".activity.MainActivity");

            // 4. 键盘和权限设置
//            options.setUnicodeKeyboard(true);
//            options.setResetKeyboard(true);
            options.setAutoGrantPermissions(true);

            // 5. 会话设置
            options.setNoReset(true);
            options.setNewCommandTimeout(Duration.ofSeconds(3600));
            options.setEnsureWebviewsHavePages(true);
            options.setNativeWebScreenshot(true);
//            options.setConnectHardwareKeyboard(true);

            // 6. 雷电模拟器专用优化
            options.setCapability("systemPort", 8200);
            options.setCapability("unicodeKeyboard", true);  // 启用Unicode输入
            options.setCapability("skipDeviceInitialization", true);
            options.setCapability("skipServerInstallation", true);
            options.setCapability("disableAndroidWatchers", true);

            // 7. 移除冲突的deviceName
            // 不要设置deviceName，它会导致冲突

            // 8. 创建驱动实例（使用新端点）
            AndroidDriver driver = new AndroidDriver(new URL(APPIUM_SERVER_URL), options);
            // 9. 设置隐式等待

            // 10. 验证连接
            System.out.println("设备状态: " + driver.getStatus());
            System.out.println("当前Activity: " + driver.currentActivity());
            return driver;
        } catch (MalformedURLException e) {
            System.err.println("URL格式错误: " + e.getMessage());
        } catch (Exception e) {
            System.err.println("连接失败: " + e.getMessage());
            e.printStackTrace();
        }
        return null;
    }

    public static void main(String[] args) {
        try {
            //执行代码前，先启动
            // 1、adb devices
            // 2、adb connect 127.0.0.1:5555
            // 3、adb kill-server
            // 4、adb start-server
            AndroidDriver init = init();
            driver = init;
            testDianpingAutomation();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void testDianpingAutomation() throws Exception {
        // 1. 从桌面启动大众点评
        DesktopPage desktop = new DesktopPage(driver);
        desktop.launchDianping();

        // 2. 首页操作
        HomePage homePage = new HomePage(driver);
        try {
            Thread.sleep(15000);
        } catch (InterruptedException e) {
        }
        homePage.refreshAndWait();
        homePage.openSearch();
        // 等待结果加载
        Thread.sleep(3000);
        // 输入后隐藏键盘
        driver.hideKeyboard();
        // 或通过按返回键
//        driver.pressKey(new KeyEvent(AndroidKey.BACK));

        if (!homePage.isSearchOpened()) {
            throw new RuntimeException("搜索栏未正确打开");
        }
//        contexts = driver.getContextHandles();
//        driver.context((String) contexts.toArray()[1]); // 切换到WEBVIEW上下文
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        WebElement merchantList = wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//android.widget.FrameLayout[@content-desc=\"SearchPagerListView-商户\"]")));
        boolean elementPresent = AppiumUtils.isElementPresent(driver, By.xpath("//android.widget.FrameLayout[@content-desc=\"SearchPagerListView-商户\"]"), 15);
        if (!elementPresent){
            return;
        }
        boolean elementPresent1 = AppiumUtils.isElementPresent(driver, By.xpath("//android.widget.FrameLayout[@content-desc=\"gridView_item_wrapper\"]"), 15);
        if (!elementPresent1){
            return;
        }
        List<WebElement> merchants = merchantList.findElements(By.xpath("//android.widget.FrameLayout[@content-desc=\"gridView_item_wrapper\"]"));
        // 3. 遍历商户并提取数据
        List<MerchantInfo> merchantData = new ArrayList<>();
        // 获取所有子项 FrameLayout
// 定位到 RecyclerView 容器
        findAdvertisedShopWithScroll( driver);

        // 5. 分析结果
        int adCount = 0;
        for (MerchantInfo info : merchantData) {
            if (info.getHasAd()) {
                // 4. 选择商户
                SearchPage searchPage = new SearchPage(driver);
                searchPage.selectShopWithAd(info.getName());

                // 5. 商户详情页
                ShopPage shopPage = new ShopPage(driver);
                if (!shopPage.isPageLoaded()) {
                    throw new RuntimeException("商户页加载失败");
                }
                shopPage.openReviews();

                // 6. 评价页操作
                ReviewPage reviewPage = new ReviewPage(driver);
                reviewPage.viewMoreReviews();

                if (!reviewPage.hasMediaReviews()) {
                    throw new RuntimeException("未找到带图/视频评价");
                }

                List<String> list = reviewPage.captureHighQualityImages();
                reviewPage.navigateBack();

                // 7. 发布笔记
                PublishPage publishPage = new PublishPage(driver);
                publishPage.startCreateNote();
                publishPage.addPhotos(list);
                publishPage.generateRecommendation();
                publishPage.selectTopics(10);
                publishPage.saveAsDraft();
                adCount++;
                System.out.println("广告商户: " + info.getName() + " | 类型: " + info.getAdType());
            }
        }
        System.out.println("总商户数: " + merchantData.size() + "广告商户数: " + adCount + "广告占比: " + (adCount * 100.0 / merchantData.size()) + "%");
        Dimension size = driver.manage().window().getSize();
        int startY = (int) (size.height * 0.8);
        int endY = (int) (size.height * 0.2);

        new TouchAction<>(driver)
                .press(PointOption.point(size.width / 2, startY))
                .waitAction(WaitOptions.waitOptions(Duration.ofMillis(500)))
                .moveTo(PointOption.point(size.width / 2, endY)).release()
                .perform();

    }

    public static void findAndClickAdvertisedShop(AndroidDriver driver) {
        // 定位商户列表容器（RecyclerView）
        WebElement shopList = driver.findElement(AppiumBy.xpath(
                "//android.widget.FrameLayout[@content-desc='SearchPagerListView-商户']" +
                        "/android.widget.FrameLayout/android.support.v7.widget.RecyclerView"
        ));

        // 获取所有商户项（FrameLayout）
        List<WebElement> shopItems = shopList.findElements(AppiumBy.className("android.widget.FrameLayout"));

        // 遍历商户项查找广告
        for (WebElement shopItem : shopItems) {
            try {
                // 在商户项内查找包含"广告"的文本元素
                WebElement adTag = shopItem.findElement(AppiumBy.xpath(
                        ".//android.widget.TextView[contains(@text, '广告')]"
                ));

                // 找到广告标签后点击整个商户项
                System.out.println("发现广告商户: " + adTag.getText());
                shopItem.click();
                return; // 点击后退出循环

            } catch (org.openqa.selenium.NoSuchElementException e) {
                // 当前商户无广告标签，继续查找
            }
        }

        System.out.println("未找到含'广告'的商户");
    }

    public static void findAdvertisedShopWithScroll(AndroidDriver driver) {
        Set<String> viewedItems = new HashSet<>();
        Dimension screenSize = driver.manage().window().getSize();
        int centerX = screenSize.width / 2;

        // 最大滚动次数
        for (int i = 0; i < 5; i++) {
            WebElement shopList = driver.findElement(AppiumBy.xpath(
                    "//android.widget.FrameLayout[@content-desc='SearchPagerListView-商户']" +
                            "/android.widget.FrameLayout/android.support.v7.widget.RecyclerView"
            ));

            List<WebElement> shopItems = shopList.findElements(
                    AppiumBy.className("android.widget.FrameLayout")
            );

            for (WebElement shop : shopItems) {
                String shopId = shop.getAttribute("resource-id");
                if (shopId != null && !viewedItems.contains(shopId)) {
                    viewedItems.add(shopId);

                    try {
                        WebElement adTag = shop.findElement(AppiumBy.xpath(
                                ".//android.widget.TextView[contains(@text, '广告')]"
                        ));
                        System.out.println("发现广告商户: " + adTag.getText());
                        shop.click();
                        return;
                    } catch (Exception e) {
                        // 忽略无广告的商户
                    }
                }
            }

            // 执行滚动（从底部滑动到顶部）
            new TouchAction(driver)
                    .press(PointOption.point(centerX, (int)(screenSize.height * 0.8)))
                    .waitAction(WaitOptions.waitOptions(Duration.ofMillis(800)))
                    .moveTo(PointOption.point(centerX, (int)(screenSize.height * 0.3)))
                    .release()
                    .perform();

            // 等待新内容加载
            try { Thread.sleep(2000); } catch (Exception e) {}
        }
        System.out.println("滚动结束，未找到广告商户");
    }

    // 多维度检测广告标记
    public static WebElement isAdMerchant(WebElement merchant) {
        // 方式1: 特定文本检测
        try {
            WebElement adText = merchant.findElement(
                    By.xpath(".//*[contains(@text, '广告') or contains(@text, 'Promoted')]")
            );
            return adText;
        } catch (NoSuchElementException e) {
        }

        // 方式2: 特定图标检测
        try {
            WebElement adIcon = merchant.findElement(
                    By.xpath(".//*[contains(@content-desc, 'ad') or contains(@resource-id, 'ad_marker')]")
            );
            return adIcon;
        } catch (NoSuchElementException e) {
        }

        // 方式3: 特殊样式检测 (如角标、边框)
        String bgColor = merchant.getCssValue("background-color");
        if (bgColor.equals("#FFFDE7") || bgColor.equals("rgba(255, 253, 231, 1)")) {
            return null; // 广告商户特殊背景色
        }

        return null;
    }

    // 提取更多商户信息
    public MerchantInfo extractMerchantInfo(WebElement merchant) {
        MerchantInfo info = new MerchantInfo();

        // 基础信息
        info.setName(getTextSafe(merchant, "com.dianping.v1:id/tv_title"));
        info.setRating(getTextSafe(merchant, "com.dianping.v1:id/tv_comment_score"));
        info.setReviewCount(getTextSafe(merchant, "com.dianping.v1:id/tv_comment_count"));

        // 价格信息
        try {
            info.setPrice(merchant.findElement(
                    By.id("com.dianping.v1:id/tv_price")
            ).getText().replace("¥", ""));
        } catch (Exception e) {
            info.setPrice("未知");
        }

        // 广告检测
        WebElement adMerchant = isAdMerchant(merchant);
        if (null != adMerchant) {
            info.setHasAd(true);
        }
        return info;
    }

    private String getTextSafe(WebElement parent, String id) {
        try {
            return parent.findElement(By.id(id)).getText();
        } catch (Exception e) {
            return "";
        }
    }

    public void tearDown() {
        if (driver != null) {
            driver.quit();
        }
    }
}